/*******************************************************************************
 * Package: com.hngtrust.iir.company.controller
 * Type:    AiController
 * Date:    2021-4-28 16:56
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.company.controller;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.hngtrust.framework.bind.ResponseInfo;
import com.hngtrust.framework.security.util.SecurityUtils;
import com.hngtrust.iir.company.controller.vo.*;
import com.hngtrust.iir.company.dto.ListMapRelationRespDTO;
import com.hngtrust.iir.company.service.CompHolderService;
import com.hngtrust.iir.company.service.CompManagementService;
import com.hngtrust.iir.company.service.CompanyService;
import com.hngtrust.iir.exception.IirErrorType;
import com.hngtrust.iir.exception.IirException;
import com.hngtrust.iir.user.entity.User;
import com.hngtrust.iir.util.DateUtils;
import com.tiger.util.MyHttpClient;
import com.tiger.web.service.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * AI接口
 * @author Chentianyong
 * @date 2021-4-28 16:56
 */
@Slf4j
@Api(tags = "AI接口")
@RestController
@RequestMapping("/company")
public class AiController {
    
    private static final MyHttpClient MY_HTTP_CLIENT = new MyHttpClient();
    //处理http请求返回结果对象
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
    @Autowired
    private CompanyService companyService;
    
    @Autowired
    private CompManagementService compManagementService;
    
    @Autowired
    private CompHolderService compHolderService;
    
    @Value("${ai.enterprise-queryCompany.url:}")
    private String queryMapByCompany;
    
    @Value("${ai.enterprise-queryPerson.url:}")
    private String queryMapByPerson;
    
    @Value("${ai.enterpriseRelation-query.url:}")
    private String queryMapRelation;

    @Value("${ai.id-card.url}")
    private String aiIdcardUrl;

    @Value("${tiger.minio.out.address}")
    private String minioAddress;

    @Value("${ai.idcard.minio}")
    private String minioIdcard;

    @Autowired
    @Qualifier("minIoFileService")
    private FileService fileService;
    
    
    /**
     * 根据公司查询企业图谱
     */
    @ApiOperation(value = "根据公司查询企业图谱", notes = "根据公司查询企业图谱")
    @PostMapping("/list-map-by-company")
    public ResponseInfo<ListMapByCompanyRespVo> listMapByCompany(
            @ApiParam(value = "根据公司查询企业图谱") @Valid @RequestBody AiCompanyReqVO req) {
        log.info("AiController.listMapByCompany start...");
        
        if(req.getName().isEmpty()){
            throw new IirException(IirErrorType.INTFACE_PARAMS_ERROR,"name");
        }
    
        ListMapByCompanyRespVo resp = null;
        try {
            // 发送http请求
            Map<String, Object> params = Maps.newHashMap();
            params.put("enterpriseStandardName", req.getName());
            params.put("credit_Code","");
            String result = MY_HTTP_CLIENT.postJson(queryMapByCompany, params);
            log.info("根据公司查询企业图谱数据成功：{}", result);
            JsonNode readTree = OBJECT_MAPPER.readTree(result);
            //返回结果
            if (checkResult(result, readTree)) {
                JsonNode dataJson = readTree.get("data");
                if (null != dataJson) {
                    resp = OBJECT_MAPPER.readValue(dataJson.toString(), ListMapByCompanyRespVo.class);
                }
            }
        } catch (Exception e) {
            log.error("根据公司查询企业图谱，公司名称：{}错误：{}", req.getName(),e);
        }
        
        ResponseInfo<ListMapByCompanyRespVo> data = new ResponseInfo<>();
        data.setData(resp);
        return data;
    }
    
    
    /**
     * 根据个人查询企业图谱
     */
    @ApiOperation(value = "根据个人查询企业图谱", notes = "根据个人查询企业图谱")
    @PostMapping("/list-map-by-person")
    public ResponseInfo<ListMapByPersonRespVo> listMapByPerson(
            @ApiParam(value = "根据个人查询企业图谱") @Valid @RequestBody AiCompanyReqVO req) {
        log.info("AiController.listMapByPerson start...");
        
        if(req.getName().isEmpty()){
            throw new IirException(IirErrorType.INTFACE_PARAMS_ERROR,"name");
        }
        
        ListMapByPersonRespVo resp = null;
        try {
            // 发送http请求
            Map<String, Object> params = Maps.newHashMap();
            params.put("person_name", req.getName());
            String result = MY_HTTP_CLIENT.postJson(queryMapByPerson, params);
            log.info("根据个人查询企业图谱数据成功：{}", result);
            JsonNode readTree = OBJECT_MAPPER.readTree(result);
            //返回结果
            if (checkResult(result, readTree)) {
                JsonNode dataJson = readTree.get("data");
                if (null != dataJson) {
                    resp = OBJECT_MAPPER.readValue(dataJson.toString(), ListMapByPersonRespVo.class);
                }
            }
        } catch (Exception e) {
            log.error("根据个人查询企业图谱，名称：{}错误：{}", req.getName(),e);
        }
        
        ResponseInfo<ListMapByPersonRespVo> data = new ResponseInfo<>();
        data.setData(resp);
        return data;
    }
    
    
    /**
     * 查询企业关系图谱
     */
    @ApiOperation(value = "查询企业关系图谱", notes = "查询企业关系图谱")
    @PostMapping("/list-map-relation")
    public ResponseInfo<ListMapRelationRespDTO> listMapRelation(
            @ApiParam(value = "查询企业关系图谱") @Valid @RequestBody AiCompanyReqVO req) {
        log.info("AiController.listMapRelation start...");
        
        if(req.getName().isEmpty()){
            throw new IirException(IirErrorType.INTFACE_PARAMS_ERROR,"name");
        }
        
        ListMapRelationRespDTO resp = null;
        try {
            // 发送http请求
            Map<String, Object> params = Maps.newHashMap();
            params.put("enterpriseStandardName", req.getName());
            params.put("creditCode", "");
            String result = MY_HTTP_CLIENT.postJson(queryMapRelation, params);
            log.info("查询企业关系图谱成功：{}", result);
            JsonNode readTree = OBJECT_MAPPER.readTree(result);
            //返回结果
            if (checkResult(result, readTree)) {
                JsonNode dataJson = readTree.get("data");
                if (null != dataJson) {
                    resp = OBJECT_MAPPER.readValue(dataJson.toString(), ListMapRelationRespDTO.class);
                }
            }
        } catch (Exception e) {
            log.error("查询企业关系图谱，名称：{}错误：{}", req.getName(),e);
        }
        //查询个人的统计数
        if(null != resp && null != resp.getNodes()){
            List<String> names = new ArrayList<>();
            for(ListMapRelationRespDTO.Node node : resp.getNodes()){
                if(null !=  node.getType() && node.getType().equals("1") && null != node.getName()){
                    names.add(node.getName());
                }
            }
            if(!names.isEmpty()){
                //担任法人的公司数
                List<ListMapRelationRespDTO.Node> nodes = companyService.chairmanCount(names);
                for(ListMapRelationRespDTO.Node chairman : nodes){
                    for(ListMapRelationRespDTO.Node node : resp.getNodes()){
                        if(chairman.getName().equals(node.getName())){
                            node.setRepresentCompanyNum(chairman.getRepresentCompanyNum());
                        }
                    }
                }
                //对外投资的公司数
                nodes = compHolderService.nameCount(names);
                for(ListMapRelationRespDTO.Node chairman : nodes){
                    for(ListMapRelationRespDTO.Node node : resp.getNodes()){
                        if(chairman.getName().equals(node.getName())){
                            node.setOutboundInvestNum(chairman.getOutboundInvestNum());
                        }
                    }
                }
                //在外任职对应的公司数
                nodes = compManagementService.nameCount(names);
                for(ListMapRelationRespDTO.Node chairman : nodes){
                    for(ListMapRelationRespDTO.Node node : resp.getNodes()){
                        if(chairman.getName().equals(node.getName())){
                            node.setCompaniesNum(chairman.getCompaniesNum());
                        }
                    }
                }
                //控股企业的个数
                nodes = compHolderService.nameCountControl(names);
                for(ListMapRelationRespDTO.Node chairman : nodes){
                    for(ListMapRelationRespDTO.Node node : resp.getNodes()){
                        if(chairman.getName().equals(node.getName())){
                            node.setHoldingEnterpriseNum(chairman.getHoldingEnterpriseNum());
                        }
                    }
                }
            }
        }
        
        ResponseInfo<ListMapRelationRespDTO> data = new ResponseInfo<>();
        data.setData(resp);
        return data;
    }
    
    /**
     * 检查调用AI系统返回结果
     */
    private boolean checkResult(String values, JsonNode readTree) {
        if (StringUtil.isNotBlank(values) && readTree != null) {
            JsonNode resultNode = readTree.get("code");
            if (null == resultNode) {
                return false;
            }
            
            String result = resultNode.asText();
            if ("0".equals(result)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根据身份证解析
     */
    @ApiOperation(value = "根据身份证解析", notes = "根据身份证解析")
    @PostMapping("/id-card-identification")
    public ResponseInfo<AiIdCardRespVO> idCardIdentification(@ApiParam("上传参数") @RequestParam(required = true) MultipartFile file)
    {
        log.info("AiController.idCardIdentification start...");
        if(file.isEmpty()){
            throw new IirException(IirErrorType.INTFACE_PARAMS_ERROR,"file");
        }
        AiIdCardRespVO resp = null;
        try {
            String path = minioIdcard + DateUtils.getTodayString() + "/";
            String directory = System.getProperty("java.io.tmpdir");
            User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();

            String substring = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String fileName = loginUser.getId().toString() + substring;
            File tempFile = new File(directory, fileName);
            file.transferTo(tempFile);//保存文件
            log.info("开始上传文件");
            String retPath = fileService.upload(tempFile, path, true);
            log.info("上传结束");

            AiIdCardReqVO bo = new AiIdCardReqVO();
            bo.setImgPath(retPath);
            String result = null;
            result = MY_HTTP_CLIENT.postJson(aiIdcardUrl, bo);
            log.info("根据身份证解析数据成功：{}", result);
            JsonNode readTree = OBJECT_MAPPER.readTree(result);
                //返回结果
                if (checkResult(result, readTree)) {
                    JsonNode dataJson = readTree.get("data");
                    if (null != dataJson) {
                        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                        resp = OBJECT_MAPPER.readValue(dataJson.toString(), AiIdCardRespVO.class);
                    }
                }
            } catch (Exception e) {
                log.error("根据身份证解析数据错误");
            }
            resp.setMinioPath(minioAddress+resp.getMinioPath());
            ResponseInfo<AiIdCardRespVO> data = new ResponseInfo<>();
            data.setData(resp);
            return data;
        }

}
